package com.vmove.childtrain.activity;

import android.os.Bundle;
import android.os.CountDownTimer;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.RadioGroup;
import android.widget.TextView;

import com.jaygoo.widget.OnRangeChangedListener;
import com.jaygoo.widget.RangeSeekBar;
import com.vmove.childtrain.R;
import com.vmove.childtrain.common.Constants;
import com.vmove.childtrain.db.dao.LightDao;
import com.vmove.childtrain.db.entity.Light;
import com.vmove.childtrain.domain.IdStepColor;
import com.vmove.childtrain.domain.TeamData;
import com.vmove.childtrain.fragment.DegreeDialog_lesson2;
import com.vmove.childtrain.protocol.CommandType;
import com.vmove.childtrain.protocol.LightCMD;
import com.vmove.childtrain.protocol.detail.LightCMD_Close;
import com.vmove.childtrain.protocol.detail.LightCMD_Close_All;
import com.vmove.childtrain.utils.TimeUtils;
import com.vmove.childtrain.utils.ToastUtils;
import com.vmove.childtrain.utils.UIUtils;
import com.vmove.childtrain.view.MyCheckBox;
import com.vmove.childtrain.view.Panel;
import com.vmove.childtrain.view.interpolator.EasingType;
import com.vmove.childtrain.view.interpolator.ExpoInterpolator;
import com.vmove.childtrain.view.media.PlayView;

import java.sql.SQLException;
import java.util.List;
import java.util.Random;
import java.util.Vector;

import androidx.fragment.app.FragmentManager;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;


/**
 * 课程12 消灭小白人 随机与上一个不重复
 */
public class Lesson12_NRActivity extends BaseLessonActivity {

    @BindView(R.id.playView)
    PlayView playView;
    byte color1 = LightCMD.Color.RED.getByte();
    byte color2 = LightCMD.Color.YELLOW.getByte();
    byte color3 = LightCMD.Color.BLUE.getByte();
    byte color4 = LightCMD.Color.GREEN.getByte();
    byte color5 = LightCMD.Color.PURPLE.getByte();
    byte color6 = LightCMD.Color.QING.getByte();
    @BindView(R.id.cb_lightNum)
    MyCheckBox cbLightNum;
    @BindView(R.id.seekbar_lightNum)
    RangeSeekBar seekbarLightNum;
    @BindView(R.id.cb_lightColor)
    MyCheckBox cbLightColor;
    @BindView(R.id.cb_userNum)
    MyCheckBox cbUserNum;
    @BindView(R.id.seekbar_userNum)
    RangeSeekBar seekbarUserNum;
    @BindView(R.id.cb_time)
    MyCheckBox cbTime;
    @BindView(R.id.seekbar_time)
    RangeSeekBar seekbarTime;
    @BindView(R.id.cb_stepNum)
    MyCheckBox cbStepNum;
    @BindView(R.id.seekbar_stepNum)
    RangeSeekBar seekbarStepNum;
    @BindView(R.id.tv_timeCountDown)
    TextView tvTimeCountDown;
    @BindView(R.id.ib_show)
    ImageButton ibShow;

    private LightDao lightDao;
    /**
     * 当前熄灭的灯集合
     */
    private Vector<Integer> offLights;
    /**
     * 点亮的灯集合
     */
    private Vector<IdStepColor> onLights;
    private List<Light> allLights;
    private boolean isStart = false;
    /**
     * 同时亮灯个数
     */
    private volatile int numberOn = 6;
    /**
     * 灯总数
     */
    private int total;
    /**
     * 点亮灯个数
     */
    volatile int onCount = 0;
    private Random random;
    /**
     * 亮灯指令
     */
    private LightCMD lightCMD;

    private TeamData teamDataRed;
    private TeamData teamDataYellow;
    private TeamData teamDataBlue;
    private TeamData teamDataGreen;
    private TeamData teamDataPurple;
    private TeamData teamDataQing;
    private FragmentManager fragmentManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lesson12);
        ButterKnife.bind(this);
        initData();
        initView();
        initSettings();
    }

    private void initData() {
        offLights = new Vector<>();
        onLights = new Vector<>();
        lightDao = new LightDao(this);
        random = new Random();
        try {
            allLights = lightDao.getAllLights();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        total = allLights.size();
        teamDataRed = new TeamData();
        teamDataYellow = new TeamData();
        teamDataBlue = new TeamData();
        teamDataGreen = new TeamData();
        teamDataPurple = new TeamData();
        teamDataQing = new TeamData();
        fragmentManager = getSupportFragmentManager();
        initProtocalCMD();
    }

    private void initView() {
        cbTime.setIntValue(seconds);
        seekbarLightNum.setValue(6f);
        seekbarLightNum.setRange(1, total);
        seekbarTime.setValue(seconds);
        seekbarLightNum.setOnRangeChangedListener(seekBarChangeListener);
        seekbarStepNum.setOnRangeChangedListener(seekBarChangeListener);
        seekbarTime.setOnRangeChangedListener(seekBarChangeListener);
        seekbarUserNum.setOnRangeChangedListener(seekBarChangeListener);
    }

    private OnRangeChangedListener seekBarChangeListener = new OnRangeChangedListener() {

        @Override
        public void onRangeChanged(RangeSeekBar view, float leftValue, float rightValue, boolean isFromUser) {
            int leftValueInt = (int) leftValue;
            switch (view.getId()) {
                case R.id.seekbar_lightNum:
                    numberOn = leftValueInt;
                    cbLightNum.setIntValue(leftValueInt);
                    seekbarLightNum.setIndicatorText(leftValueInt + "个");
                    break;
                case R.id.seekbar_userNum:
                    cbUserNum.setIntValue(leftValueInt);
                    seekbarUserNum.setIndicatorText(leftValueInt + "人");
                    break;
                case R.id.seekbar_time:
                    seconds = leftValueInt;
                    cbTime.setIntValue(leftValueInt);
                    seekbarTime.setIndicatorText(leftValueInt + "秒");
                    break;
                case R.id.seekbar_stepNum:
                    cbStepNum.setIntValue(leftValueInt);
                    seekbarStepNum.setIndicatorText(leftValueInt + "步");
                    break;
            }
        }

        @Override
        public void onStartTrackingTouch(RangeSeekBar view, boolean isLeft) {

        }

        @Override
        public void onStopTrackingTouch(RangeSeekBar view, boolean isLeft) {

        }
    };

    @OnClick(R.id.playView)
    public void onViewClicked() {
        if (!isStart) {//开始
            startRun();
        } else {//停止
            stopRun();
        }
    }

    private boolean isShow=false;
    @OnClick(R.id.ib_show)
    public void clickShowButton() {
        //正在执行 不允许预演
        if (isStart){
            return;
        }
        if (!isShow) {
            //show
            isShow = true;
            ibShow.setImageResource(R.drawable.hand_stop);
            //todo 开启预演
            offLights.clear();
            for (int i = 0; i < total; i++) {
                offLights.add(allLights.get(i).getLightId());
            }
            onCount=0;
            lightOn(color1);
            lightOn(color2);
            lightOn(color3);
            lightOn(color4);
        } else {
            //close
            writeSerialByte(new LightCMD_Close_All().getBytes());
            ibShow.setImageResource(R.drawable.hand_start);
            isShow = false;
        }
    }

    /**
     * 步骤计数 用于生成步骤码
     */
    int stepCount = 0;
    /**
     * 执行时间 /秒
     */
    private int seconds=40;
    private CountDownTimer timer;
    private long countdownTime;

    /**
     * isStart变量 开始时最后置true ，结束时最先置false
     * 防止非本次执行的返回包影响
     */
    @Override
    public void startRun() {
        //todo 输入校验
        if (seconds <=0){
            UIUtils.showToastSafe("时间必须大于0");
            playView.setChecked(false);
            return;
        }
        if (isShow){
            UIUtils.showToastSafe("请先结束预演！");
            playView.setChecked(false);
            return;
        }
        super.startRun();
        offLights.clear();
        for (int i = 0; i < total; i++) {
            offLights.add(allLights.get(i).getLightId());
        }
        teamDataGreen.reset();
        teamDataBlue.reset();
        teamDataYellow.reset();
        teamDataRed.reset();
        teamDataPurple.reset();
        teamDataQing.reset();
        onCount=0;
        stepCount=0;
        //开启倒计时
        countdownTime = seconds * 1000;
        countdownTime();
        //亮灯
        lightOn(color1);
        isStart = true;
        if (numberOn>1){
            lightOn(color2);
        }
        if (numberOn>2){
            lightOn(color3);
        }
        if (numberOn>3){
            lightOn(color4);
        }
        if (numberOn>4){
            lightOn(color5);
        }
        if (numberOn>5){
            lightOn(color6);
        }
    }

    @Override
    public void stopRun() {
        super.stopRun();
        isStart = false;
        onLights.clear();
        onCount = 0;
        //关闭灯
//        writeSerialByte(new LightCMD_Close_All().getBytes());
        for (Light light:allLights) {
            writeSerialByte(new LightCMD_Close().setLight(light.getLightId()).getBytes());
        }
        playView.setChecked(false);
        if (null != timer) {
            timer.cancel();
            timer = null;
            tvTimeCountDown.setText("00分00秒");
        }
        //todo 弹出成绩窗体
        DegreeDialog_lesson2 degreeDialog_lesson2 = new DegreeDialog_lesson2();
        Bundle bundle = new Bundle();
        bundle.putParcelable("degreeRed", teamDataRed);
        bundle.putParcelable("degreeYellow", teamDataYellow);
        bundle.putParcelable("degreeGreen", teamDataGreen);
        bundle.putParcelable("degreeBlue", teamDataBlue);
        degreeDialog_lesson2.setArguments(bundle);
        degreeDialog_lesson2.show(fragmentManager, "degreeDialog");
    }

    //倒计时的方法
    private void countdownTime() {
        timer = new CountDownTimer(countdownTime, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                //todo 显示时间
                String s = TimeUtils.convertToDifftime(TimeUtils.FORMAT_DAY_CN_3, millisUntilFinished);
                tvTimeCountDown.setText(s);
            }

            @Override
            public void onFinish() {
                stopRun();
            }
        }.start();
    }

    /**
     * 随机点亮一个灯,并指定颜色
     */
    public synchronized void lightOn(byte color) {
        stepCount++;
        int index = random.nextInt(total - onCount);
        //从灭灯序列中随机移除一个并返回
        Integer lightId = offLights.remove(index);
        int stepNo = stepCount % 255;
        onLights.add(new IdStepColor(lightId, stepNo, color));
        writeSerialByte(lightCMD.setStepNum(stepNo).setLightColor(color).setLight(lightId).getBytes());
        onCount++;
    }

    /**
     * 随机点亮一个灯,并指定颜色
     */
    public synchronized void lightOn(byte color,int offLight) {
        stepCount++;
        int index = random.nextInt(total - onCount);
        //从灭灯序列中随机移除一个并返回
        Integer lightId = offLights.remove(index);
        int stepNo = stepCount % 255;
        onLights.add(new IdStepColor(lightId, stepNo, color));
        offLights.add(offLight);
        writeSerialByte(lightCMD.setStepNum(stepNo).setLightColor(color).setLight(lightId).getBytes());
        onCount++;
    }

    @Override
    public void onSerialReceivedData(byte[] data) {
        if (data.length < 6) {
            UIUtils.showToastSafe("数据长度错误,请检测使用环境");
            return;
        }
        if (data[5] == CommandType.COMMAND_LIGHT_R) {//亮灯触发回复
            if (isStart) {
                parseLightR(data);
            }
        }
    }

    private synchronized void parseLightR(byte[] data) {
        //触发的light
        int lightId = data[4] & 0xff;
        //触发耗时 ms
        int time = ((data[11] & 0xff) << 24) | ((data[10] & 0xff) << 16) | ((data[9] & 0xff) << 8) | (data[8] & 0xff);
        //触发源
        byte source = data[6];
        //步骤码
        int stepNumber = data[7] & 0xff;
        IdStepColor idAndStep = new IdStepColor(lightId, stepNumber);
        int index = onLights.indexOf(idAndStep);
        if (index >= 0) {
            IdStepColor closeLight = onLights.get(index);
            switch (closeLight.getColor()){
                case 0x01://红
                    teamDataRed.addTime(time);
                    teamDataRed.addSuccess();
                    break;
                case 0x04://黄
                    teamDataYellow.addTime(time);
                    teamDataYellow.addSuccess();
                    break;
                case 0x03://蓝
                    teamDataBlue.addTime(time);
                    teamDataBlue.addSuccess();
                    break;
                case 0x02://绿
                    teamDataGreen.addTime(time);
                    teamDataGreen.addSuccess();
                    break;
            }
            onLights.remove(closeLight);
//            offLights.add(lightId);
            onCount--;
            lightOn(closeLight.getColor(),lightId);
        } else {
            UIUtils.showToastSafe(idAndStep.toString());
        }
    }

    @Override
    public String returnToolBarTitle() {
        return "";
    }


    //----------属性设置 start-------
    @BindView(R.id.rightPanel)
    Panel panel;
    @BindView(R.id.seekbar_lightBrightness)
    RangeSeekBar seekbarLightBrightness;
    @BindView(R.id.rg_color_after)
    RadioGroup rgColorAfter;
    @BindView(R.id.seekbar_time_after)
    RangeSeekBar seekbarTimeAfter;
    @BindView(R.id.seekbar_infrared_sensitivity)
    RangeSeekBar seekbarInfraredSensitivity;
    @BindView(R.id.seekbar_pat_sensitivity)
    RangeSeekBar seekbarPatSensitivity;
    @BindView(R.id.rg_checkmode)
    RadioGroup rgCheckmode;
    @BindView(R.id.rg_lightmode)
    RadioGroup rgLightmode;
    @BindView(R.id.rg_voicemode)
    RadioGroup rgVoicemode;
    @BindView(R.id.bt_save)
    Button btSave;

    private int lightBrightness = Constants.LIGHT_BRIGHTNESS;
    private int checkTimeAfter = 0;
    private int infraredSensitivity = Constants.INFRARED_SENSITIVITY;
    private int patSensitivity = Constants.PAT_SENSITIVITY;
    private byte colorAfterCheck = LightCMD.Color.NULL.getByte();
    private byte checkMode = LightCMD.CheckMode.ALL.getByte();
    private byte voiceMode = LightCMD.VoiceMode.STARTVOICE.getByte();
    private byte lightMode = LightCMD.LightMode.NULL.getByte();
    //----------属性设置 end-------


    /*--------------属性设置初始化- start------------*/
    private void initSettings() {
        panel.setInterpolator(new ExpoInterpolator(EasingType.Type.OUT));
        seekbarPatSensitivity.setValue(patSensitivity);
        seekbarInfraredSensitivity.setValue(infraredSensitivity);
        seekbarLightBrightness.setValue(lightBrightness);
        seekbarTimeAfter.setValue(checkTimeAfter);

        seekbarLightBrightness.setOnRangeChangedListener(settingSeekBarChangeListener);
        seekbarTimeAfter.setOnRangeChangedListener(settingSeekBarChangeListener);
        seekbarInfraredSensitivity.setOnRangeChangedListener(settingSeekBarChangeListener);
        seekbarPatSensitivity.setOnRangeChangedListener(settingSeekBarChangeListener);

        rgColorAfter.setOnCheckedChangeListener(settingRadioButtonCheckChangeListener);
        rgCheckmode.setOnCheckedChangeListener(settingRadioButtonCheckChangeListener);
        rgLightmode.setOnCheckedChangeListener(settingRadioButtonCheckChangeListener);
        rgVoicemode.setOnCheckedChangeListener(settingRadioButtonCheckChangeListener);
    }

    @OnClick(R.id.bt_save)
    public void onSaveClicked() {
        lightCMD.setLightBrightness(lightBrightness)
                .setFinalLightColor(colorAfterCheck)
                .setFinalTimeLast(checkTimeAfter)
                .setInfraredSensitivity(infraredSensitivity)
                .setPatSensitivity(patSensitivity)
                .setCheckMode(checkMode)
                .setLightFlash(lightMode)
                .setLightVoice(voiceMode);
        ToastUtils.toastSuccess(this, "保存成功！", 0);
    }

    private void initProtocalCMD() {
        lightCMD = new LightCMD();
        lightCMD.setLightBrightness(lightBrightness)
                .setFinalLightColor(colorAfterCheck)
                .setFinalTimeLast(checkTimeAfter)
                .setInfraredSensitivity(infraredSensitivity)
                .setPatSensitivity(patSensitivity)
                .setCheckMode(checkMode)
                .setLightFlash(lightMode)
                .setLightVoice(voiceMode);
    }

    /**
     * 属性设置中的回调
     */
    private OnRangeChangedListener settingSeekBarChangeListener = new OnRangeChangedListener() {

        @Override
        public void onRangeChanged(RangeSeekBar view, float leftValue, float rightValue, boolean isFromUser) {
            int leftValueInt = (int) leftValue;
            switch (view.getId()) {
                case R.id.seekbar_lightBrightness:
                    lightBrightness = leftValueInt;
                    seekbarLightBrightness.setIndicatorText(leftValueInt + "");
                    break;
                case R.id.seekbar_time_after:
                    checkTimeAfter = leftValueInt;
                    seekbarTimeAfter.setIndicatorText(leftValueInt + "");
                    break;
                case R.id.seekbar_infrared_sensitivity:
                    infraredSensitivity = leftValueInt;
                    seekbarInfraredSensitivity.setIndicatorText(leftValueInt + "");
                    break;
                case R.id.seekbar_pat_sensitivity:
                    patSensitivity = leftValueInt;
                    seekbarPatSensitivity.setIndicatorText(leftValueInt + "");
                    break;
            }
        }

        @Override
        public void onStartTrackingTouch(RangeSeekBar view, boolean isLeft) {

        }

        @Override
        public void onStopTrackingTouch(RangeSeekBar view, boolean isLeft) {

        }
    };

    /**
     * 属性设置radiobutton 回调
     */
    private RadioGroup.OnCheckedChangeListener settingRadioButtonCheckChangeListener = new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            switch (checkedId) {
                case R.id.rb_color_hong_after:
                    colorAfterCheck = LightCMD.Color.RED.getByte();
                    break;
                case R.id.rb_color_lv_after:
                    colorAfterCheck = LightCMD.Color.GREEN.getByte();
                    break;
                case R.id.rb_color_lan_after:
                    colorAfterCheck = LightCMD.Color.BLUE.getByte();
                    break;
                case R.id.rb_color_qing_after:
                    colorAfterCheck = LightCMD.Color.QING.getByte();
                    break;
                case R.id.rb_color_zi_after:
                    colorAfterCheck = LightCMD.Color.PURPLE.getByte();
                    break;
                case R.id.rb_color_huang_after:
                    colorAfterCheck = LightCMD.Color.YELLOW.getByte();
                    break;
                case R.id.rb_color_bai_after:
                    colorAfterCheck = LightCMD.Color.WHITE.getByte();
                    break;
                case R.id.rb_color_null_after:
                    colorAfterCheck = LightCMD.Color.NULL.getByte();
                    break;
                case R.id.rb_checkmode_all:
                    checkMode = LightCMD.CheckMode.ALL.getByte();
                    break;
                case R.id.rb_checkmode_infrared:
                    checkMode = LightCMD.CheckMode.Infrared.getByte();
                    break;
                case R.id.rb_checkmode_pat:
                    checkMode = LightCMD.CheckMode.PAT.getByte();
                    break;
                case R.id.rb_lightmode_all:
                    lightMode = LightCMD.LightMode.ALLLIGHT.getByte();
                    break;
                case R.id.rb_lightmode_start:
                    lightMode = LightCMD.LightMode.STARTLIGHT.getByte();
                    break;
                case R.id.rb_lightmode_null:
                    lightMode = LightCMD.LightMode.NULL.getByte();
                    break;
                case R.id.rb_voicemode_check:
                    voiceMode = LightCMD.VoiceMode.SENSEVOICE.getByte();
                    break;
                case R.id.rb_voicemode_start:
                    voiceMode = LightCMD.VoiceMode.STARTVOICE.getByte();
                    break;
                case R.id.rb_voicemode_null:
                    voiceMode = LightCMD.VoiceMode.NULL.getByte();
                    break;
            }
        }
    };
    /*--------------属性设置初始化-end------------*/

}
